package com.law.lawcaculator.service.impl;

import com.googlecode.aviator.AviatorEvaluator;
import com.law.lawcaculator.mapper.CalculationRulesMapper;
import com.law.lawcaculator.mapper.RegionConfigsMapper;
import com.law.lawcaculator.model.entity.CalculationRules;
import com.law.lawcaculator.model.entity.RegionConfigs;
import com.law.lawcaculator.service.RuleEngineService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@RequiredArgsConstructor
@Slf4j
public class RuleEngineServiceImpl implements RuleEngineService {

    private final CalculationRulesMapper calculationRulesMapper;
    private final RegionConfigsMapper regionConfigsMapper;

    @Override
    public Object evaluateExpression(String expression, Map<String, Object> context) {
        try {
            // 预处理上下文，确保数值类型的变量不为null且可以计算
            Map<String, Object> processedContext = new HashMap<>(context);
            
            // 提取表达式中的变量名
            Set<String> variables = extractVariables(expression);
            
            // 处理每个变量
            for (String var : variables) {
                Object value = processedContext.get(var);
                
                // 如果变量为null，设置为0
                if (value == null) {
                    processedContext.put(var, 0);
                    log.warn("Variable {} is null, set to 0 for calculation", var);
                } 
                // 如果是字符串，尝试转换为数字
                else if (value instanceof String) {
                    try {
                        // 尝试将字符串转换为数字
                        double numValue = Double.parseDouble((String) value);
                        processedContext.put(var, numValue);
                    } catch (NumberFormatException e) {
                        // 非数字字符串，保持原样
                        log.debug("Variable {} is a non-numeric string: {}", var, value);
                    }
                }
            }
            
            return AviatorEvaluator.execute(expression, processedContext);
        } catch (Exception e) {
            log.error("Expression evaluation failed: {}", expression, e);
            throw new RuntimeException("Expression evaluation error", e);
        }
    }
    
    /**
     * 从表达式中提取变量名
     * @param expression 表达式字符串
     * @return 变量名集合
     */
    private Set<String> extractVariables(String expression) {
        Set<String> variables = new HashSet<>();
        // 简单的正则表达式，匹配可能的变量名（以字母或下划线开头，后跟字母、数字或下划线）
        Pattern pattern = Pattern.compile("\\b[a-zA-Z_]\\w*\\b");
        Matcher matcher = pattern.matcher(expression);
        
        while (matcher.find()) {
            String var = matcher.group();
            // 排除常见的Aviator关键字和函数
            if (!isKeyword(var)) {
                variables.add(var);
            }
        }
        
        return variables;
    }
    
    /**
     * 检查是否为Aviator关键字或常用函数名
     */
    private boolean isKeyword(String word) {
        Set<String> keywords = Set.of(
            "if", "else", "true", "false", "nil", "and", "or", "not", "in", 
            "map", "filter", "reduce", "count", "sum", "max", "min", "avg"
        );
        return keywords.contains(word);
    }

    @Override
    public Map<String, Object> executeCalculationRules(String sessionId, Map<String, Object> userData) {
        Map<String, Object> results = new HashMap<>();

        // 1. 构建上下文，包括用户数据和地区配置
        Map<String, Object> context = new HashMap<>();
        context.putAll(userData);

        // 2. 加载地区配置（如果有地区信息）
//        String region = (String) userData.get("region");
//        if (region != null) {
//            loadRegionConfig(region, context);
//        }

        // 3. 获取所有有效的计算规则
        List<CalculationRules> rules = calculationRulesMapper.selectList(null);
        rules = rules.stream()
                .filter(rule -> rule.getIsActive() == 1)
                .sorted(Comparator.comparing(CalculationRules::getSortOrder))
                .toList();

        // 4. 执行规则计算
        for (CalculationRules rule : rules) {
            // 检查触发条件
            if (rule.getConditionExpression() != null) {
                Boolean shouldExecute = (Boolean) evaluateExpression(rule.getConditionExpression(), context);
                if (shouldExecute == null || !shouldExecute) {
                    continue;
                }
            }

            // 执行计算公式
            Object result = evaluateExpression(rule.getCalculationExpression(), context);
            String outputKey = rule.getOutputKey();
            results.put(outputKey, result);
            context.put(outputKey, result); // 将结果放入上下文供后续规则使用

            log.info("Rule executed: {}, result: {}", rule.getRuleName(), result);
        }

        return results;
    }

    private void loadRegionConfig(String region, Map<String, Object> context) {
        try {
            // 查询地区配置
            RegionConfigs regionConfig = regionConfigsMapper.selectList(null).stream()
                    .filter(config -> config.getIsActive() == 1 && (
                            region.equals(config.getRegionName()) || region.equals(config.getRegionCode())))
                    .findFirst()
                    .orElse(null);

            if (regionConfig != null && regionConfig.getConfig() instanceof Map) {
                Map<String, Object> configMap = (Map<String, Object>) regionConfig.getConfig();
                // 例如：将北京的平均工资放入上下文，键名为 beijing_avg_salary
                String regionKey = region.toLowerCase().replace("广东", "guangdong") // 处理常见地区
                        .replace("上海", "shanghai")
                        .replace("北京", "beijing");
                
                configMap.forEach((key, value) -> {
                    context.put(regionKey + "_" + key, value);
                });
            }
        } catch (Exception e) {
            log.error("Failed to load region config for {}", region, e);
        }
    }
}